<?php

namespace App\Http\Controllers\Admin;

use App\Console\Commands\WalletBalance;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Wallet;
use App\Models\Currency;
use App\Models\Property;
use App\Models\PropertyInfo;
use App\Models\Turn;
use App\Models\Message;
use App\Library\ETH\EthereumFunction;
use App\Library\BTC\BitcoinFunction;
use App\Library\OBA\ObaFunction;
use DB;
use Exception;

/**
 * 系统钱包管理
 */
class WalletController extends Controller
{
    public function __construct()
    {
        view()->share('menu', 'wallet');
    }

    /**
     * 系统钱包列表
     * @param  Request $request [description]
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function wallet_list(Request $request)
    {
        //订单状态
        $status = $request->get('status') ?? 99;
        //币种id
        $cid = $request->get('cid') ?? 99;
        //钱包地址
        $address = $request->get('address') ?? '';
        //条件查询
        $data = Wallet::where(function ($query) use ($status) {
            if ($status != 99 && in_array($status, [0, 1])) {
                $query->where('status', $status);
            }
        })
        ->where(function($query) use ($address) {
            if ($address != 99 && strlen($address) > 0) {
                $query->where('address', $address);
            }
        })
        ->where(function ($query) use ($cid) {
            if ($cid != 99) {
                $query->where('cid', $cid);
            }
        })
        ->orderBy('created_at', 'desc')->paginate(8);
        //分页索引值
        $page_num = $data->firstItem();
        //除USDT外其他币种
        $currs = Currency::whereIn('is_standard', [0, 2])->get();

        return view('admin/wallet/wallet_list', compact('data', 'page_num', 'status', 'currs', 'cid', 'address'));
    }

    /**
     * 已分配用户钱包地址列表
     * @param  Request $request [description]
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function allot_wallet_list(Request $request)
    {
        //订单状态
        $status = $request->get('status') ?? 99;
        //币种id
        $cid = $request->get('cid') ?? 99;
        //钱包地址
        $address = $request->get('address') ?? '';
        //条件查询
        $data = Turn::where(['type' => 1])
            ->where(function ($query) use ($status) {
                if ($status != 99) {
                    $query->where('status', $status);
                }
            })
            ->where(function ($query) use ($cid) {
                if ($cid != 99) {
                    $query->where('cid', $cid);
                }
            })
            ->where(function ($query) use ($address) {
                if ($address != 99 && strlen($address) > 0) {
                    $query->where('wallet_address', $address);
                }
            })
            ->orderBy('created_at', 'desc')->paginate(8);
        //分页索引值
        $page_num = $data->firstItem();
        //除USDT外其他币种
        $currs = Currency::whereIn('is_standard', [0, 2])->get();

        return view('admin/wallet/allot_wallet_list', compact('data', 'page_num', 'status','cid', 'address', 'currs'));
    }

    /**
     * 用户提币申请
     * @param  Request $request [description]
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View [type]           [description]
     */
    public function withdraw_list(Request $request)
    {
        //订单状态
        $status = $request->get('status') ?? 99;
        //币种id
        $cid = $request->get('cid') ?? 99;
        //钱包地址
        $address = $request->get('address') ?? '';
        //条件查询
        $data = Turn::where(['type' => 2])
            ->where(function($query) use ($status) {
                if ($status != 99) {
                    $query->where('status', $status);
                }
            })
            ->where(function ($query) use ($cid) {
                if ($cid != 99) {
                    $query->where('cid', $cid);
                }
            })
            ->where(function ($query) use ($address) {
                if ($address != 99 && strlen($address) > 0) {
                    $query->where('wallet_address', $address);
                }
            })
            ->orderBy('created_at', 'desc')->paginate(8);
        //分页索引
        $page_num = $data->firstItem();
        //除USDT外其他币种
        $currs = Currency::whereIn('is_standard', [0, 2])->get();

        return view('admin/wallet/withdraw_list', compact('data', 'page_num', 'status','cid','address','currs'));
    }

    /**
     * 查询地址余额
     * @param  Request $request [description]
     * @return \Illuminate\Http\RedirectResponse
     */
    public function get_address_balance(Request $request)
    {
        //系统钱包id
        $wallet_id = $request->get('wallet_id');
        //查找钱包
        $wallet = Wallet::find($wallet_id);
        //未找到该钱包

        if (!$wallet) {
            //错误提示
            return back()->with(['status' => 0, 'msg' => '钱包不存在']);
        }
        //以太坊
        if ($wallet->currency->name_en == 'ETH') {
            //以太坊操作类
            $eth = new EthereumFunction();
            //验证钱包地址
            $valid = $eth->addressValidator($wallet->address);
            //验证失败
            if (!$valid) {
                //错误提示
                return back()->with(['status' => 0, 'msg' => '地址不合法']);
            }
            //查询当前地址余额
            $balance = $eth->getBalanceByAddress($wallet->address);
            //查询发生错误
            if ($balance == "") {
                return back()->with(['status' => 0, 'msg' => '以太坊节点未工作']);
            }
            //返回余额提示
            return back()->with(['status' => 1, 'msg' => '地址余额为：'.$balance]);
        }
        //比特币
        if (in_array($wallet->currency->name_en, ['BTC','LTC','DGC'])) {
            //比特币操作类
            $btc = new BitcoinFunction($wallet->currency->name_en);
            //验证地址
            $valid = $btc->addressValidator($wallet->address);
            //验证失败
            if (!$valid) {
                //错误提示
                return back()->with(['status' => 0, 'msg' => '地址不合法']);
            }
            //查找余额
            $balance = $btc->getBalanceByAddress($wallet->address);
            //返回余额提示
            return back()->with(['status' => 1, 'msg' => '地址余额为：'.$balance]);
        }
        //OBA
        if ($wallet->currency->name_en == 'OBA') {
            //OBA操作类
            $oba  = new ObaFunction();
            //验证钱包地址
            $valid = $oba->addressValidator($wallet->address);
            //验证失败
            if (!$valid) {
                //错误提示
                return back()->with(['status' => 0, 'msg' => $valid['msg']]);
            }
            //查找地址当前余额
            $balance = $oba->getBalanceByAddress($wallet->address);
            //发生错误
            if (is_array($balance)) {
                //返回错误提示
                return back()->with(['status' => 0, 'msg' => $balance['msg']]);
            }
            //返回余额提示
            return back()->with(['status' => 1, 'msg' => '地址余额为：'.$balance]);
        }
        //以上条件不满足，返回错误提示
        return back()->with(['status' => 0, 'msg' => '不支持该地址查询']);
    }

    /**
     * 确认发币页面
     * @param  Request $request [description]
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View [type]           [description]
     */
    public function confirm_currency(Request $request)
    {
        //提币申请订单id
        $turn_id = $request->get('turn_id');
        //查找订单
        $data = Turn::find($turn_id);
        //获取该申请单对应币种的用户可用资产
        $property = Property::where(['uid' => $data->uid, 'cid' => $data->cid])->first();
        //获取系统钱包当前币种未锁定的所有地址
        $wallets = Wallet::where(['cid' => $data->cid, 'status' => 0])->get();

        return view('admin/wallet/confirm_currency', compact('data', 'property', 'wallets'));
    }

    /**
     * 执行发币操作
     * @param  Request $request [description]
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function confirm_send_currency(Request $request)
    {
        try {
            //状态初始值
            $status = 0;
            //订单id
            $turn_id = $request->get('turn_id');
            //钱包id
            $wallet_id = $request->get('wallet_id');
            //查找订单
            $turn = Turn::find($turn_id);
            //未找到订单
            if (!$turn) {
                //抛出错误
                throw new Exception('订单无效');
            }
            //查找钱包
            $wallet = Wallet::find($wallet_id);
            //钱包不存在
            if (!$wallet) {
                //抛出错误
                throw new Exception('钱包无效');
            }
            //查询用户锁定资产
            $balance = $turn->user->currency_property($turn->cid)->first()->blocked ?? 0;
            //锁定资产小于提现额度
            if ($balance < $turn->real_num) {
                //抛出错误
                throw new Exception('用户余额不足提现！');
            }
            //判断是否支持币种
            if (!in_array($turn->currency->name_en, ['ETH','BTC','LTC','DGC','OBA'])) {
                //抛出错误
                throw new Exception('暂不支持该币种自动转出！');
            }
            //开启事务
            DB::beginTransaction();
            //OBA
            if ($turn->currency->name_en == 'OBA') {
                //OBA处理类
                $oba = new ObaFunction();
                //验证用户钱包地址是否有效
                $valid = $oba->addressValidator($turn->wallet_address);
                //地址验证失败
                if (!$valid) {
                    //抛出错误
                    throw new Exception('地址不合法');
                }
                //钱包当前余额
                $balance = $oba->getBalanceByAddress($wallet->address);
                //余额小于等于实际提现数量
                if ($balance <= $turn->real_num) {
                    //抛出错误
                    throw new Exception('系统钱包当前余额不足！');
                }
                /*
                //发币地址
                $fromAccount = $wallet->address;
                //私钥
                $privateKey = $wallet->private_key;
                //用户账号
                $toAccount = $turn->wallet_address;
                //发起交易
                $res = $oba->makeTransaction($turn->real_num, $fromAccount, $toAccount, $privateKey);
                //交易错误
                if ($res['status'] == 0) {
                    //抛出错误
                    throw new Exception($res['msg']);
                }
                */
            }
            //以太币
            if ($turn->currency->name_en == 'ETH') {
                //以太坊处理类
                $ethereum = new EthereumFunction();
                //验证用户钱包地址是否有效
                $valid = $ethereum->addressValidator($turn->wallet_address);
                //验证失败
                if (!$valid) {
                    //抛出错误
                    throw new Exception('地址不合法');
                }
                //钱包当前余额
                $balance = $ethereum->getBalanceByAddress($wallet->address);
                //余额小于等于提现实际数量
                if ($balance <= $turn->real_num) {
                    //抛出错误
                    throw new Exception('系统钱包当前余额不足！');
                }
                /*
                //发币地址
                $fromAccount = $wallet->address;
                //用户账号
                $toAccount = $turn->wallet_address;
                //转为wei单位
                $wei = $ethereum->toWei($turn->real_num);
                //转16进制
                $value = $ethereum->toHex($wei);
                //发起交易 (待跟踪)
                $res = $ethereum->makeTransaction($fromAccount, $toAccount, $value);
                //发生错误
                if (isset($res['status']) && $res['status'] == 0) {
                    //return back()->with(['status' => 0, 'msg' => '发起交易失败']);
                    throw new Exception('发起交易失败');
                }
                */
            }
            //比特币，莱特币，狗币
            if (in_array($turn->currency->name_en, ['BTC','LTC','DGC'])) {
                //比特币处理类
                $btc = new BitcoinFunction($turn->currency->name_en);
                //验证用户钱包地址
                $check = $btc->addressValidator($turn->wallet_address);
                //验证失败
                if (!$check) {
                    //抛出错误
                    throw new Exception('地址不合法');
                }
                //当前余额
                $balance = $btc->getBalanceByAddress($wallet->address);
                //余额小于等于提现实际数
                if ($balance <= $turn->real_num) {
                    //抛出错误
                    throw new Exception('系统钱包当前余额不足！');
                }
                /*
                //发币地址
                $fromAddresses = $wallet->address;
                //发起交易（待完善）
                $res = $btc->makeTransaction($turn->real_num, $fromAddresses, $turn->wallet_address);
                //dd($res);
                */
            }
            /*
            //用户资产
            $property = Property::where(['uid' => $turn->uid, 'cid' => $turn->cid])->first();
            //减少余额
            $property->decrement('blocked', $turn->num);
            //减少总资产
            $property->decrement('total', $turn->num);
            //写入资产详情
            PropertyInfo::create([
                'uid' => $turn->uid,
                'cid' => $turn->cid,
                'oid' => $turn->id,
                'note' => '提币',
                'num' => $turn->real_num,
                'price' => 0,
                'total' => 0,
                'proc' => $turn->proc,
                'type' => 8,
                'deal_type' => 1,
                'status' => 1
            ]);
            */
            //修改turn表
            $turn->update(['status' => 4, 'wallet_id' => $wallet_id]);
            //锁定钱包
            $wallet->update(['status' => 1]);
            /*
            //写入消息
            $msgArr = [
                'msg_id' => 13,
                'uid' => $turn->id,
                'message' => [$turn->currency->name_en,$turn->address,$turn->real_num],
                'push_message' => [$turn->currency->name_en],
            ];
            (new Message())->syspublishsmsAll($msgArr);
            */

            //提交事务
            DB::commit();

            //执行成功跳转到提币申请列表页
            return redirect('/admin/withdraw_list');

        } catch (Exception $e) {
            //回滚事务
            DB::rollback();
            //接收错误提示
            $msg = $e->getMessage();

            return back()->with(['status' => 0, 'msg' => $msg]);
        }
    }

    /**
     * 取消提币申请
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function reject_apply(Request $request)
    {
        //提币申请订单id
        $turn_id = $request->get('turn_id');
        //查找订单
        $turn = Turn::find($turn_id);
        //修改状态
        $turn->update(['status' => 3]);
        //解冻资产
        $property = Property::where(['uid' => $turn->uid, 'cid' => $turn->cid])->first();
        $property->increment('balance', $turn->num);
        $property->decrement('blocked', $turn->num);

        //返回操作提示
        return back()->with(['status' => 1, 'msg' => '申请已取消']);
    }
}
